
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Computed Properties - vue.js</title>
        <meta charset="utf-8">
        <meta name="description" content="Vue.js - Intuitive, Fast and Composable MVVM for building interactive interfaces.">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
        <link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,600|Roboto Mono' rel='stylesheet' type='text/css'>
        <link href='//fonts.googleapis.com/css?family=Dosis:300,500&text=Vue.js' rel='stylesheet' type='text/css'>
        <link href="//cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css" rel='stylesheet' type='text/css'>
        <link rel="icon" href="/images/logo.png" type="image/x-icon">
        <script>
            window.PAGE_TYPE = "guide"
        </script>
        <link rel="stylesheet" href="/css/page.css">
        <script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-46852172-1', 'vuejs.org');
  ga('send', 'pageview');
</script>
        <script src="/js/vue.js"></script>
    </head>
    <body>
        <div id="mobile-bar">
            <a class="menu-button"></a>
            <a class="logo" href="/"></a>
        </div>
        
            <div id="header">
    <a id="logo" href="/">
        <img src="/images/logo.png">
        <span>Vue.js</span>
    </a>
    <ul id="nav">
        <li>
  <form id="search-form">
    <input type="text" id="search-query-nav" class="search-query st-default-search-input">
  </form>
</li>
<li><a href="/guide/" class="nav-link current">Guide</a></li>
<li><a href="/api/" class="nav-link">API</a></li>
<li><a href="/examples/" class="nav-link">Examples</a></li>
<li><a href="/blog/" class="nav-link">Blog</a></li>
<li class="nav-dropdown-container">
  <a class="nav-link">Community</a><span class="arrow"></span>
  <ul class="nav-dropdown">
    <li><a href="https://github.com/vuejs/vue" class="nav-link" target="_blank">GitHub</a></li>
    <li><a href="http://forum.vuejs.org" class="nav-link" target="_blank">Forum</a></li>
    <li><a href="https://gitter.im/vuejs/vue" class="nav-link" target="_blank">Chat</a></li>
    <li><a href="https://twitter.com/vuejs" class="nav-link" target="_blank">Twitter</a></li>
  </ul>
</li>


    </ul>
</div>

            <div id="main">
                
                    
    <div class="sidebar">
    <ul class="main-menu">
        <li>
  <form id="search-form">
    <input type="text" id="search-query-sidebar" class="search-query st-default-search-input">
  </form>
</li>
<li><a href="/guide/" class="nav-link current">Guide</a></li>
<li><a href="/api/" class="nav-link">API</a></li>
<li><a href="/examples/" class="nav-link">Examples</a></li>
<li><a href="/blog/" class="nav-link">Blog</a></li>
<li class="nav-dropdown-container">
  <a class="nav-link">Community</a><span class="arrow"></span>
  <ul class="nav-dropdown">
    <li><a href="https://github.com/vuejs/vue" class="nav-link" target="_blank">GitHub</a></li>
    <li><a href="http://forum.vuejs.org" class="nav-link" target="_blank">Forum</a></li>
    <li><a href="https://gitter.im/vuejs/vue" class="nav-link" target="_blank">Chat</a></li>
    <li><a href="https://twitter.com/vuejs" class="nav-link" target="_blank">Twitter</a></li>
  </ul>
</li>


    </ul>
    <div class="list">
        <div id="donate" style="margin-bottom: 20px">
            <span class="wrapper" style="width: 110px">
              <img src="/images/patreon.png">
              <a href="/support-vuejs">Support Vue.js</a>
            </span>
        </div>
        <h2>
            Guide
            <select class="version-select">
                <option value="">2.0</option>
                <option selected value="SELF">1.0</option>
                <option value="012">0.12</option>
                <option value="011">0.11</option>
            </select>
        </h2>
        <ul class="menu-root">
            
                <li>
                    <a href="/guide/installation.html" class="sidebar-link">Installation</a>
                </li>
            
                <li>
                    <a href="/guide/index.html" class="sidebar-link">Getting Started</a>
                </li>
            
                <li>
                    <a href="/guide/overview.html" class="sidebar-link">Overview</a>
                </li>
            
                <li>
                    <a href="/guide/instance.html" class="sidebar-link">The Vue Instance</a>
                </li>
            
                <li>
                    <a href="/guide/syntax.html" class="sidebar-link">Data Binding Syntax</a>
                </li>
            
                <li>
                    <a href="/guide/computed.html" class="sidebar-link current">Computed Properties</a>
                </li>
            
                <li>
                    <a href="/guide/class-and-style.html" class="sidebar-link">Class and Style Bindings</a>
                </li>
            
                <li>
                    <a href="/guide/conditional.html" class="sidebar-link">Conditional Rendering</a>
                </li>
            
                <li>
                    <a href="/guide/list.html" class="sidebar-link">List Rendering</a>
                </li>
            
                <li>
                    <a href="/guide/events.html" class="sidebar-link">Methods and Event Handling</a>
                </li>
            
                <li>
                    <a href="/guide/forms.html" class="sidebar-link">Form Input Bindings</a>
                </li>
            
                <li>
                    <a href="/guide/transitions.html" class="sidebar-link">Transitions</a>
                </li>
            
                <li>
                    <a href="/guide/components.html" class="sidebar-link">Components</a>
                </li>
            
                <li>
                    <a href="/guide/reactivity.html" class="sidebar-link">Reactivity in Depth</a>
                </li>
            
                <li>
                    <a href="/guide/custom-directive.html" class="sidebar-link">Custom Directives</a>
                </li>
            
                <li>
                    <a href="/guide/custom-filter.html" class="sidebar-link">Custom Filters</a>
                </li>
            
                <li>
                    <a href="/guide/mixins.html" class="sidebar-link">Mixins</a>
                </li>
            
                <li>
                    <a href="/guide/plugins.html" class="sidebar-link">Plugins</a>
                </li>
            
                <li>
                    <a href="/guide/application.html" class="sidebar-link">Building Large-Scale Apps</a>
                </li>
            
                <li>
                    <a href="/guide/comparison.html" class="sidebar-link">Comparison with Other Frameworks</a>
                </li>
            
                <li>
                    <a href="/guide/join.html" class="sidebar-link">Join the Vue Community!</a>
                </li>
            
        </ul>
    </div>
</div>


<div class="content guide with-sidebar">
    <div id="ad">
  <script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=vuejs" id="_carbonads_js"></script>
</div>

    <h1>Computed Properties</h1>
    <p>In-template expressions are very convenient, but they are really meant for simple operations only. Templates are meant to describe the structure of your view. Putting too much logic into your templates can make them bloated and hard to maintain. This is why Vue.js limits binding expressions to one expression only. For any logic that requires more than one expression, you should use a <strong>computed property</strong>.</p>
<h3 id="Basic-Example"><a href="#Basic-Example" class="headerlink" title="Basic Example"></a>Basic Example</h3><figure class="highlight html"><table><tr><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"example"</span>&gt;</span></div><div class="line">  a=&#123;&#123; a &#125;&#125;, b=&#123;&#123; b &#125;&#125;</div><div class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></div></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><div class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> Vue(&#123;</div><div class="line">  el: <span class="string">'#example'</span>,</div><div class="line">  data: &#123;</div><div class="line">    a: <span class="number">1</span></div><div class="line">  &#125;,</div><div class="line">  computed: &#123;</div><div class="line">    <span class="comment">// a computed getter</span></div><div class="line">    b: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</div><div class="line">      <span class="comment">// `this` points to the vm instance</span></div><div class="line">      <span class="keyword">return</span> <span class="keyword">this</span>.a + <span class="number">1</span></div><div class="line">    &#125;</div><div class="line">  &#125;</div><div class="line">&#125;)</div></pre></td></tr></table></figure>
<p>Result:</p>

<div id="example" class="demo">
  a={{ a }}, b={{ b }}
</div>
<script>
var vm = new Vue({
  el: '#example',
  data: {
    a: 1
  },
  computed: {
    b: function () {
      return this.a + 1
    }
  }
})
</script>

<p>Here we have declared a computed property <code>b</code>. The function we provided will be used as the getter function for the property <code>vm.b</code>:</p>
<figure class="highlight js"><table><tr><td class="code"><pre><div class="line"><span class="built_in">console</span>.log(vm.b) <span class="comment">// -&gt; 2</span></div><div class="line">vm.a = <span class="number">2</span></div><div class="line"><span class="built_in">console</span>.log(vm.b) <span class="comment">// -&gt; 3</span></div></pre></td></tr></table></figure>
<p>You can open the console and play with the example vm yourself. The value of <code>vm.b</code> is always dependent on the value of <code>vm.a</code>.</p>
<p>You can data-bind to computed properties in templates just like a normal property. Vue is aware that <code>vm.b</code> depends on <code>vm.a</code>, so it will update any bindings that depends on <code>vm.b</code> when <code>vm.a</code> changes. And the best part is that we’ve created this dependency relationship declaratively: the computed getter function is pure and has no side effects, which makes it easy to test and reason about.</p>
<h3 id="Computed-Property-vs-watch"><a href="#Computed-Property-vs-watch" class="headerlink" title="Computed Property vs. $watch"></a>Computed Property vs. $watch</h3><p>Vue.js does provide an API method called <code>$watch</code> that allows you to observe data changes on a Vue instance. When you have some data that needs to change based on some other data, it is tempting to use <code>$watch</code> - especially if you are coming from an AngularJS background. However, it is often a better idea to use a computed property rather than an imperative <code>$watch</code> callback. Consider this example:</p>
<figure class="highlight html"><table><tr><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"demo"</span>&gt;</span>&#123;&#123;fullName&#125;&#125;<span class="tag">&lt;/<span class="name">div</span>&gt;</span></div></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="code"><pre><div class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> Vue(&#123;</div><div class="line">  el: <span class="string">'#demo'</span>,</div><div class="line">  data: &#123;</div><div class="line">    firstName: <span class="string">'Foo'</span>,</div><div class="line">    lastName: <span class="string">'Bar'</span>,</div><div class="line">    fullName: <span class="string">'Foo Bar'</span></div><div class="line">  &#125;</div><div class="line">&#125;)</div><div class="line"></div><div class="line">vm.$watch(<span class="string">'firstName'</span>, <span class="function"><span class="keyword">function</span> (<span class="params">val</span>) </span>&#123;</div><div class="line">  <span class="keyword">this</span>.fullName = val + <span class="string">' '</span> + <span class="keyword">this</span>.lastName</div><div class="line">&#125;)</div><div class="line"></div><div class="line">vm.$watch(<span class="string">'lastName'</span>, <span class="function"><span class="keyword">function</span> (<span class="params">val</span>) </span>&#123;</div><div class="line">  <span class="keyword">this</span>.fullName = <span class="keyword">this</span>.firstName + <span class="string">' '</span> + val</div><div class="line">&#125;)</div></pre></td></tr></table></figure>
<p>The above code is imperative and repetitive. Compare it with a computed property version:</p>
<figure class="highlight js"><table><tr><td class="code"><pre><div class="line"><span class="keyword">var</span> vm = <span class="keyword">new</span> Vue(&#123;</div><div class="line">  el: <span class="string">'#demo'</span>,</div><div class="line">  data: &#123;</div><div class="line">    firstName: <span class="string">'Foo'</span>,</div><div class="line">    lastName: <span class="string">'Bar'</span></div><div class="line">  &#125;,</div><div class="line">  computed: &#123;</div><div class="line">    fullName: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</div><div class="line">      <span class="keyword">return</span> <span class="keyword">this</span>.firstName + <span class="string">' '</span> + <span class="keyword">this</span>.lastName</div><div class="line">    &#125;</div><div class="line">  &#125;</div><div class="line">&#125;)</div></pre></td></tr></table></figure>
<p>Much better, isn’t it?</p>
<h3 id="Computed-Setter"><a href="#Computed-Setter" class="headerlink" title="Computed Setter"></a>Computed Setter</h3><p>Computed properties are by default getter-only, but you can also provide a setter when you need it:</p>
<figure class="highlight js"><table><tr><td class="code"><pre><div class="line"><span class="comment">// ...</span></div><div class="line">computed: &#123;</div><div class="line">  fullName: &#123;</div><div class="line">    <span class="comment">// getter</span></div><div class="line">    get: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</div><div class="line">      <span class="keyword">return</span> <span class="keyword">this</span>.firstName + <span class="string">' '</span> + <span class="keyword">this</span>.lastName</div><div class="line">    &#125;,</div><div class="line">    <span class="comment">// setter</span></div><div class="line">    set: <span class="function"><span class="keyword">function</span> (<span class="params">newValue</span>) </span>&#123;</div><div class="line">      <span class="keyword">var</span> names = newValue.split(<span class="string">' '</span>)</div><div class="line">      <span class="keyword">this</span>.firstName = names[<span class="number">0</span>]</div><div class="line">      <span class="keyword">this</span>.lastName = names[names.length - <span class="number">1</span>]</div><div class="line">    &#125;</div><div class="line">  &#125;</div><div class="line">&#125;</div><div class="line"><span class="comment">// ...</span></div></pre></td></tr></table></figure>
<p>Now when you call <code>vm.fullName = &#39;John Doe&#39;</code>, the setter will be invoked and <code>vm.firstName</code> and <code>vm.lastName</code> will be updated accordingly.</p>
<p>The technical details behind how computed properties are updated are <a href="reactivity.html#Inside-Computed-Properties">discussed in another section</a> dedicated to the reactivity system.</p>

    
      <div class="guide-links">
        
          <span>← <a href="/guide/syntax.html">Data Binding Syntax</a></span>
        
        
          <span style="float:right"><a href="/guide/class-and-style.html">Class and Style Bindings</a> →</span>
        
      </div>
    
    <div class="footer">
      Caught a mistake or want to contribute to the documentation?
      <a href="https://github.com/vuejs/vuejs.org/blob/master/src/guide/computed.md" target="_blank">
        Edit this page on Github!
      </a>
    </div>
</div>

                
            </div>
            <script src="//cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script>
            <script src="/js/smooth-scroll.min.js"></script>
            <script src="/js/common.js"></script>
        

        <script src="//cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.min.js"></script><script src="https://cdn.jsdelivr.net/gh/shentao/vuejs-outdated-docs-modal@v1.3/prompt.min.js"></script>
        <script>
            document.addEventListener('DOMContentLoaded', function() {
                FastClick.attach(document.body);
            }, false);
        </script>
    </body>
</html>
